package com.zh.modules.app.utils;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.zh.common.vo.PageQuery;
import org.springframework.util.StringUtils;

import java.util.Map;
import java.util.function.Consumer;

public class Condition {
    public static <T> IPage<T> getPage(PageQuery query) {
        return PageUtils.toPage(query);
    }

    public static <T> QueryWrapper<T> getQueryWrapper(T entity) {
        return new QueryWrapper(entity);
    }

    public static <T> QueryWrapper<T> getQueryWrapper(Map<String, Object> query, Class<T> clazz) {
        QueryWrapper<T> qw = new QueryWrapper();
        qw.setEntity(ConvertUtils.transfer(query, () -> {
            try {
                return clazz.newInstance();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }));
        query.remove("pageNo");
        query.remove("pageSize");
        query.remove("ascs");
        query.remove("descs");
        SqlKeyword.buildCondition(query, qw);
        return qw;
    }

    /**
     * 支持模糊查询
     *
     * @param query
     * @param clazz
     * @param fuzzyFields 模糊查询字段
     * @param <T>
     * @return
     */
    public static <T> QueryWrapper<T> getFuzzyQueryWrapper(Map<String, Object> query, Class<T> clazz, String[] fuzzyFields) {
        String fuzzy = (String) query.get(SqlKeyword.FUZZY);
        query.remove(SqlKeyword.FUZZY);
        QueryWrapper<T> qw = getQueryWrapper(query, clazz);
        if (StringUtils.isEmpty(fuzzy)) {
            return qw;
        }

        if (fuzzyFields == null || fuzzyFields.length == 0) {
            return qw;
        }

        Consumer<QueryWrapper<T>> point = null;
        for (String fuzzyField : fuzzyFields) {
            Consumer<QueryWrapper<T>> tmp = qr -> qr.like(fuzzyField, fuzzy);
            Consumer<QueryWrapper<T>> or = qr -> qr.or();
            if (point == null) {
                point = tmp.andThen(or);
            } else {
                point = point.andThen(tmp).andThen(or);
            }
        }
        qw.and(point);

        return qw;
    }

}
